package api

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
	"shop_srv_api/user_web/forms"
	"shop_srv_api/user_web/global"
	"shop_srv_api/user_web/middlewares"
	"shop_srv_api/user_web/models"
	"shop_srv_api/user_web/proto"
	"strconv"
	"strings"
	"time"
)

// HandlerGrpcErrorToHttpError grpc 状态码转为http状态码
func HandlerGrpcErrorToHttpError(err error, c *gin.Context) {
	if err != nil {
		s, ok := status.FromError(err)
		if ok {
			switch s.Code() {
			case codes.NotFound:
				c.JSON(http.StatusNotFound, gin.H{"msg": s.Message()})
			case codes.Internal:
				c.JSON(http.StatusInternalServerError, gin.H{"msg": "内部错误"})
			default:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": "其他错误" + s.Message(),
				})
			}
		}
	}
}

func GetUsrList(ctx *gin.Context) {

	claims, _ := ctx.Get("claims")
	customClaims := claims.(*models.CustomClaims)
	zap.S().Infof("访问用户:%d", customClaims.ID)
	pn, _ := strconv.Atoi(ctx.DefaultQuery("pn", "0"))
	pInt, _ := strconv.Atoi(ctx.DefaultQuery("pSize", "10"))

	list, err := global.UserSrvClient.GetUserList(ctx, &proto.PageInfo{Pn: uint32(pn), PSize: uint32(pInt)})
	if err != nil {
		zap.S().Errorw("查询用户列表失败", "msg", err.Error())
		HandlerGrpcErrorToHttpError(err, ctx)
		return
	}
	result := make([]interface{}, 0)
	for _, v := range list.Data {
		data := make(map[string]interface{})
		data["id"] = v.Id
		data["password"] = v.Password
		data["gender"] = v.Gender
		result = append(result, data)
	}
	ctx.JSON(http.StatusOK, result)
}
func RemoveTopStruct(fields map[string]string) map[string]string {
	rsp := map[string]string{}
	for f, err := range fields {
		rsp[f[strings.Index(f, ".")+1:]] = err
	}
	return rsp
}

func Login(ctx *gin.Context) {
	form := forms.PasswordLoginForm{}
	if err := ctx.ShouldBind(&form); err != nil {
		//TODO 后续封装一个方法 如何返回错误信息
		errors, ok := err.(validator.ValidationErrors)
		if !ok {
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		ctx.JSON(http.StatusBadRequest, gin.H{"error": RemoveTopStruct(errors.Translate(global.Trans))})
		return
	}
	verify := store.Verify(form.CaptChaId, form.CaptCha, false)
	if !verify {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg": "验证码错误",
		})
		return
	}
	rsp, err := global.UserSrvClient.GetUserByMobile(ctx, &proto.MobileRequest{Mobile: form.Mobile})
	if err != nil {
		if s, ok := status.FromError(err); ok {
			switch s.Code() {
			case codes.NotFound:
				ctx.JSON(http.StatusBadRequest, gin.H{"msg": "用户不存在"})
			default:
				ctx.JSON(http.StatusInternalServerError, gin.H{"msg": "登录失败"})
			}
			return
		}
		return
	} else {
		info, err := global.UserSrvClient.CheckPasswordInfo(ctx, &proto.PasswordCheckInfo{Password: rsp.Password})
		if err != nil {
			ctx.JSON(http.StatusInternalServerError, gin.H{"msg": "密码错误"})
		} else {
			if info.Success {
				j := middlewares.NewJWT()
				c := models.CustomClaims{ID: uint(rsp.Id), NickName: rsp.NickName, AuthorityId: uint(rsp.Role),
					StandardClaims: jwt.StandardClaims{NotBefore: time.Now().Unix(), //签名生效时间
						ExpiresAt: time.Now().Unix() + 60*60,
						Issuer:    "huran",
					}}
				token, err := j.CreateToken(c)
				if err != nil {
					ctx.JSON(http.StatusInternalServerError, gin.H{"msg": "生成token失败"})
					return
				}
				ctx.JSON(http.StatusOK, gin.H{"msg": "登录成功", "id": rsp.Id, "nickName": rsp.NickName, "token": token, "ExpiresAt": time.Now().Unix() + 60*60})
			} else {
				ctx.JSON(http.StatusOK, gin.H{"msg": "登录失败"})

			}
		}
	}
}
